/******************************************************************************
  * @file    		blt_kernel.c
  * @version        V1.1
  * @date    		2024-08-10
  * @author   		maqi
  * @gitee          https://gitee.com/asfdin
  * @Description
 ******************************************************************************/
#include "public_head.h"
#include "uart/bsp_uart.h"
#include "app_timer.h"

volatile sysTimestamp_t sysTimestamp = {
    .baseTimestamp = 0,
    .remTicks = 0,
    .prevClockTicks = 0,
};

static volatile taskControl_t taskControl;		    //内核控制器

volatile taskHandle_t idleTask_Handle = NULL;       //空闲任务句柄

static volatile app_timer_id_t  sleep_timer;        //作为MCU sleep模式的唤醒定时器使用


/*定时器时间到 / 唤醒睡眠*/
void sleep_timer_callback(void * p_arg)        
{	
//    app_timer_stop((app_timer_id_t)sleep_timer);
    app_timer_stop_api((app_timer_id_t *)&sleep_timer); 
	
	/*设置为正常运行状态*/
	pwr_mgmt_mode_set(PMR_MGMT_ACTIVE_MODE);	
}

void kernelWakeupInit(void)
{
    hal_pwr_set_wakeup_condition(PWR_WKUP_COND_TIMER|PWR_WKUP_COND_EXT);  /*唤醒条件*/
    hal_pwr_config_ext_wakeup(PWR_EXTWKUP_PIN2,PWR_EXTWKUP_TYPE_RISING);  /*唤醒源 运动传感器INT脚*/	

    /* 创建唤醒定时器，仅用做低功耗唤醒 */
    app_timer_create((app_timer_id_t *)&sleep_timer, ATIMER_ONE_SHOT, sleep_timer_callback);    	
}

/***********************************************************
 *
 * @func	: getKernelTimestamp
 *
 * @params	: None
 *
 * @return	: kernelTimestamp : 当前时间戳(us)
 *
 * @brief	: 获取当前实时时间戳(us)
 *
 * @info	: mq@2024/08/10
 *
 */
uint64_t getKernelTimestamp_Back(void)  //us
{
	uint32_t clockTicks = 0;                         //当前时钟节拍数
	uint64_t elapsedClockTicks = 0;                  //已经过去的时钟节拍数
    uint32_t elapsedus = 0;                          //已经过去的时间(单位us)

	// 获取当前RTC时钟数
	clockTicks = getRTCClock();

	/** Check that time has passed. **/
    // 时钟数是否发生变化
	if (clockTicks != sysTimestamp.prevClockTicks)
	{
        /* 判断时钟计数是否溢出 */
		if (clockTicks >= sysTimestamp.prevClockTicks)
		{
			elapsedClockTicks = clockTicks - sysTimestamp.prevClockTicks;        //计算过去的节拍数
            elapsedClockTicks *= TIME_UINT;
			elapsedus = elapsedClockTicks/CLOCK_FREQ;
			sysTimestamp.baseTimestamp += elapsedus;
		}
		else
		{
            if((sysTimestamp.prevClockTicks-clockTicks)<CLOCK_OVER)
            {
                return sysTimestamp.baseTimestamp;
            }
            GR_LOG(" over [%d][%d][%d]... \r\n", (sysTimestamp.prevClockTicks-clockTicks), sysTimestamp.prevClockTicks, clockTicks);
			elapsedClockTicks = (0xFFFFFFFF - sysTimestamp.prevClockTicks) + clockTicks + 1;
            elapsedClockTicks *= TIME_UINT;
			elapsedus = elapsedClockTicks/CLOCK_FREQ;
			sysTimestamp.baseTimestamp += elapsedus;
		}


		//计算剩余时钟数
		sysTimestamp.remTicks += (elapsedClockTicks % (CLOCK_FREQ));

		if (sysTimestamp.remTicks >= (CLOCK_FREQ))
		{
			sysTimestamp.baseTimestamp += (sysTimestamp.remTicks/CLOCK_FREQ);

			sysTimestamp.remTicks %= (CLOCK_FREQ);
		}

		sysTimestamp.prevClockTicks = clockTicks;
    }

	return sysTimestamp.baseTimestamp;
}


/***********************************************************
 *
 * @func	: IdleTask
 *
 * @params	: None
 *
 * @return	: None
 *
 * @brief	: 空闲任务(must)
 *
 * @info	: mq@2024/08/10
 *
 */
void IdleTask(void)
{
    GR_LOG(" [kernel] task %s \r\n", taskControl.taskHandle->pTaskName);
}


/***********************************************************
 *
 * @func	: taskControlInit
 *
 * @params	: None
 *
 * @return	: None
 *
 * @brief	: 调度内核初始化
 *
 * @info	: mq@2024/08/10
 *
 */
int kernelInit(void)
{
    int retStatus = 0;
    
    kernelWakeupInit();
    memset((void *)&taskControl, 0, sizeof(taskControl_t));
    taskControl.taskNum = 0;
	taskControl.taskInExec = KERNEL_TASK_NOT_EXEC;
    
    //必须添加空闲任务，否则调度器无法进行休眠；空闲任务的优先级为最低
    retStatus = xCreateStaticTask((taskHandle_t *)&idleTask_Handle, IdleTask, KERNEL_TASK_NUM-1, IDLE_TASK_INTERVAL, KERNEL_TASK_MODE_CYCLE, KERNEL_TASK_POWER_SLEEP, "idle_task(must)");
    if(KERNEL_SUCCESS != retStatus)
    {
        return KERNEL_ERR_INIT_IDLE_NOCREATE;
    }
    return KERNEL_SUCCESS;
}


/***********************************************************
 *
 * @func	: xTaskNameGet
 *
 * @params	: None
 *
 * @return	: 任务说明
 *
 * @brief	: 获取当前任务的说明
 *
 * @info	: mq@2024/08/10
 *
 */
char *xTaskNameGet(void)
{
	return taskControl.taskHandle->pTaskName;
}


/***********************************************************
 *
 * @func	: xTaskControlUpdate
 *
 * @params	: None
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 更新任务控制器
 *
 * @info	: mq@2024/08/10
 *
 */
static int xTaskControlUpdate(void)
{
    int minTaskIndex = -1;
    kernelTime_t minExecuteTime = (kernelTime_t)(-1);
	
    if((0 >= taskControl.taskNum) || (KERNEL_TASK_NUM < taskControl.taskNum))
    {
        return 0;
    }
    for(int i=0; i<KERNEL_TASK_NUM; i++)
    {
        if(KERNEL_TASK_VALID != taskControl.task[i].taskValid)
        {
            continue;
        }
        if(KERNEL_TASK_STATUS_SUSPEND == taskControl.task[i].taskStatus)
        {
            continue;
        }
        if(minExecuteTime > taskControl.task[i].taskExecuteTime)
        {
            minExecuteTime = taskControl.task[i].taskExecuteTime;
            minTaskIndex = i;
        }
    }
    if((-1) == minTaskIndex)
    {
        return 1;
    }
    taskControl.taskHandle = (taskHandle_t)&taskControl.task[minTaskIndex];
    return 0;
}


/***********************************************************
 *
 * @func	: xCreateTask
 *
 * @params	: pTaskHandle : 任务句柄指针;     taskCB : 任务回调;    
 *			  taskInt : 任务间隔;    taskMode : 任务模式;
 *			  taskPower : 任务功耗控制;    pTaskName : 任务说明指针;
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 创建任务(此API不能指定任务优先级，会从高到低创建)
 *
 * @info	: mq@2024/08/10
 *
 */
int xCreateTask(taskHandle_t *pTaskHandle, pCallBack taskCB, u32 taskInt, int taskMode, int taskPower, char *pTaskName)
{
    if(KERNEL_TASK_NUM <= taskControl.taskNum)
    {
        return KERNEL_ERR_OVERFLOW;
    }

    for (int i = 0; i < KERNEL_TASK_NUM; i++)
    {
        if (KERNEL_TASK_VALID != taskControl.task[i].taskValid)
        {
            taskControl.task[i].taskValid = KERNEL_TASK_VALID;
			taskControl.task[i].taskId = i;
            taskControl.task[i].taskStatus = KERNEL_TASK_STATUS_ACTIVE;
            taskControl.task[i].pTaskName = pTaskName;
            taskControl.task[i].taskExecuteTime = getKernelTimestamp() + (taskInt*1000);
            taskControl.task[i].taskInt = taskInt;
            taskControl.task[i].taskMode = taskMode;
            taskControl.task[i].taskPower = taskPower;
            taskControl.task[i].taskCB = taskCB;
            *pTaskHandle = (taskHandle_t)&taskControl.task[i];
            taskControl.taskNum ++;
			
			taskControl.powerBits &= (~(1<<i));
			if(KERNEL_TASK_POWER_ACTIVE == taskPower)
			{
				taskControl.powerBits |= (1<<i);
			}
            /* 在任务执行中不能更新任务控制器，否则可能导致任务控制器出现错误!!!! */
            if(KERNEL_TASK_NOT_EXEC == taskControl.taskInExec)
            {
                return xTaskControlUpdate();
            }
            return KERNEL_SUCCESS;
        }
    }
    return KERNEL_ERR_ABNOR;
}


/***********************************************************
 *
 * @func	: xCreateTaskDetail
 *
 * @params	: pTaskHandle : 任务句柄指针;     taskCB : 任务回调;    
*             execInt : 首次执行间隔;    taskInt : 任务执行间隔;
*			  taskMode : 任务模式;    taskPower : 任务功耗控制;
 *			  taskStatus : 任务状态(允许/挂起);    pTaskName : 任务说明指针;
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 创建任务(此API不能指定任务优先级，会从高到低创建)
 *
 * @info	: mq@2024/08/10
 *
 */
int xCreateTaskDetail(taskHandle_t *pTaskHandle, pCallBack taskCB, u32 execInt, u32 taskInt, int taskMode, int taskPower, int taskStatus, char *pTaskName)
{
    if(KERNEL_TASK_NUM <= taskControl.taskNum)
    {
        return KERNEL_ERR_OVERFLOW;
    }

    for (int i = 0; i < KERNEL_TASK_NUM; i++)
    {
        if (KERNEL_TASK_VALID != taskControl.task[i].taskValid)
        {
            taskControl.task[i].taskValid = KERNEL_TASK_VALID;
			taskControl.task[i].taskId = i;
            taskControl.task[i].taskStatus = taskStatus;
            taskControl.task[i].pTaskName = pTaskName;
            taskControl.task[i].taskExecuteTime = getKernelTimestamp() + (execInt*1000);
            taskControl.task[i].taskInt = taskInt;
            taskControl.task[i].taskMode = taskMode;
            taskControl.task[i].taskPower = taskPower;
            taskControl.task[i].taskCB = taskCB;
            *pTaskHandle = (taskHandle_t)&taskControl.task[i];
            taskControl.taskNum ++;
			
			taskControl.powerBits &= (~(1<<i));
			if((KERNEL_TASK_STATUS_ACTIVE == taskControl.task[i].taskStatus) && (KERNEL_TASK_POWER_ACTIVE == taskPower))
			{
				taskControl.powerBits |= (1<<i);
			}
            /* 在任务执行中不能更新任务控制器，否则可能导致任务控制器出现错误!!!! */
            if(KERNEL_TASK_NOT_EXEC == taskControl.taskInExec)
            {
                return xTaskControlUpdate();
            }
            return KERNEL_SUCCESS;
        }
    }
    return KERNEL_ERR_ABNOR;
}


/***********************************************************
 *
 * @func	: xCreateStaticTask
 *
 * @params	: pTaskHandle : 任务句柄指针;     taskCB : 任务回调;    taskPrio : 任务优先级;
 *			  taskInt : 任务间隔;    taskMode : 任务模式;
 *			  taskPower : 任务功耗控制;    pTaskName : 任务说明指针;
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 静态创建任务(指定任务优先级创建)
 *
 * @info	: mq@2024/08/10
 *
 */
int xCreateStaticTask(taskHandle_t *pTaskHandle, pCallBack taskCB, int taskPrio, u32 taskInt, int taskMode, int taskPower, char *pTaskName)
{
    if(KERNEL_TASK_NUM <= taskControl.taskNum)
    {
        return KERNEL_ERR_OVERFLOW;
    }
    if(KERNEL_TASK_VALID == taskControl.task[taskPrio].taskValid)
    {
        return KERNEL_ERR_OCCUPID;
    }

    taskControl.task[taskPrio].taskValid = KERNEL_TASK_VALID;
	taskControl.task[taskPrio].taskId = taskPrio;
    taskControl.task[taskPrio].taskStatus = KERNEL_TASK_STATUS_ACTIVE;
    taskControl.task[taskPrio].pTaskName = pTaskName;
    taskControl.task[taskPrio].taskExecuteTime = getKernelTimestamp() + (taskInt*1000);
    taskControl.task[taskPrio].taskInt = taskInt;
    taskControl.task[taskPrio].taskMode = taskMode;
    taskControl.task[taskPrio].taskPower = taskPower;
    taskControl.task[taskPrio].taskCB = taskCB;
    *pTaskHandle = (taskHandle_t)&taskControl.task[taskPrio];

    taskControl.taskNum ++;
	taskControl.powerBits &= (~(1<<taskPrio));
	if(KERNEL_TASK_POWER_ACTIVE == taskPower)
	{
		taskControl.powerBits |= (1<<taskPrio);
	}
    /* 在任务执行中不能更新任务控制器，否则可能导致任务控制器出现错误!!!! */
    if(KERNEL_TASK_NOT_EXEC == taskControl.taskInExec)
    {
        return xTaskControlUpdate();
    }
    return KERNEL_SUCCESS;
}

/***********************************************************
 *
 * @func	: xCreateTaskDetail
 *
* @params	: pTaskHandle : 任务句柄指针;     taskCB : 任务回调;    taskPrio : 任务优先级;
*             execInt : 首次执行间隔;    taskInt : 任务执行间隔;
*			  taskMode : 任务模式;    taskPower : 任务功耗控制;
 *			  taskStatus : 任务状态(允许/挂起);    pTaskName : 任务说明指针;
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 创建任务(此API不能指定任务优先级，会从高到低创建)
 *
 * @info	: mq@2024/08/10
 *
 */
int xCreateStaticTaskDetail(taskHandle_t *pTaskHandle, pCallBack taskCB, int taskPrio, u32 execInt, u32 taskInt, int taskMode, int taskPower, int taskStatus, char *pTaskName)
{
    if(KERNEL_TASK_NUM <= taskControl.taskNum)
    {
        return KERNEL_ERR_OVERFLOW;
    }
    if(KERNEL_TASK_VALID == taskControl.task[taskPrio].taskValid)
    {
        return KERNEL_ERR_OCCUPID;
    }

    taskControl.task[taskPrio].taskValid = KERNEL_TASK_VALID;
	taskControl.task[taskPrio].taskId = taskPrio;
    taskControl.task[taskPrio].taskStatus = taskStatus;
    taskControl.task[taskPrio].pTaskName = pTaskName;
    taskControl.task[taskPrio].taskExecuteTime = getKernelTimestamp() + (execInt*1000);
    taskControl.task[taskPrio].taskInt = taskInt;
    taskControl.task[taskPrio].taskMode = taskMode;
    taskControl.task[taskPrio].taskPower = taskPower;
    taskControl.task[taskPrio].taskCB = taskCB;
    *pTaskHandle = (taskHandle_t)&taskControl.task[taskPrio];

    taskControl.taskNum ++;
	taskControl.powerBits &= (~(1<<taskPrio));
    if((KERNEL_TASK_STATUS_ACTIVE == taskControl.task[taskPrio].taskStatus) && (KERNEL_TASK_POWER_ACTIVE == taskPower))
	{
		taskControl.powerBits |= (1<<taskPrio);
	}
    /* 在任务执行中不能更新任务控制器，否则可能导致任务控制器出现错误!!!! */
	if(KERNEL_TASK_NOT_EXEC == taskControl.taskInExec)
    {
        return xTaskControlUpdate();
    }
    return KERNEL_SUCCESS;
}

/***********************************************************
 *
 * @func	: xStartTask
 *
 * @params	: taskHandle : 任务句柄;     taskExecInt : 任务执行间隔;
 *			  taskMode : 任务模式;    taskPower : 任务功耗控制;
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
* @brief	: 启动任务(如果任务被挂起则启动任务，如果任务处于激活状态，则不做处理)
 *
 * @info	: mq@2024/08/10
 *
 */
int xStartTask(taskHandle_t taskHandle, u32 taskExecInt)
{
    task_t *pTask = (task_t *)taskHandle;
    if(NULL == taskHandle)
    {
        return KERNEL_ERR_HANLE_NULL;
    }
    if(KERNEL_TASK_VALID != pTask->taskValid)
    {
        return KERNEL_ERR_HANLE;
    }
    if (KERNEL_TASK_STATUS_ACTIVE == pTask->taskStatus)
    {
        return KERNEL_SUCCESS;
    }
    pTask->taskStatus = KERNEL_TASK_STATUS_ACTIVE;

    taskHandle->taskExecuteTime = getKernelTimestamp() + (taskExecInt*1000);
	
	taskControl.powerBits &= (~(1<<taskHandle->taskId));
	if(KERNEL_TASK_POWER_ACTIVE == taskHandle->taskPower)
	{
		taskControl.powerBits |= (1<<taskHandle->taskId);
	}
    /* 在任务执行中不能更新任务控制器，否则可能导致任务控制器出现错误!!!! */
	if(KERNEL_TASK_NOT_EXEC == taskControl.taskInExec)
    {
        return xTaskControlUpdate();
    }
    return KERNEL_SUCCESS;
}
/***********************************************************
 *
 * @func	: xRestartTask
 *
 * @params	: taskHandle : 任务句柄;     taskExecInt : 任务执行间隔;
 *			  taskMode : 任务模式;    taskPower : 任务功耗控制;
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
* @brief	: 重新启动任务
 *
 * @info	: mq@2024/08/10
 *
 */
int xRestartTask(taskHandle_t taskHandle, u32 taskExecInt, int taskMode, int taskPower)
{
    task_t *pTask = (task_t *)taskHandle;
    if(NULL == taskHandle)
    {
        return KERNEL_ERR_HANLE_NULL;
    }
    if(KERNEL_TASK_VALID != pTask->taskValid)
    {
        return KERNEL_ERR_HANLE;
    }
    if (KERNEL_TASK_STATUS_ACTIVE != pTask->taskStatus)
    {
        pTask->taskStatus = KERNEL_TASK_STATUS_ACTIVE;
    }

    taskHandle->taskExecuteTime = getKernelTimestamp() + (taskExecInt*1000);
    taskHandle->taskMode = taskMode;
    taskHandle->taskPower = taskPower;
	
	taskControl.powerBits &= (~(1<<taskHandle->taskId));
	if(KERNEL_TASK_POWER_ACTIVE == taskPower)
	{
		taskControl.powerBits |= (1<<taskHandle->taskId);
	}
    /* 在任务执行中不能更新任务控制器，否则可能导致任务控制器出现错误!!!! */
	if(KERNEL_TASK_NOT_EXEC == taskControl.taskInExec)
    {
        return xTaskControlUpdate();
    }
    return KERNEL_SUCCESS;
}
/***********************************************************
 *
 * @func	: xTaskSuspend
 *
 * @params	: taskHandle : 任务句柄;
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 将任务挂起
 *
 * @info	: mq@2024/08/10
 *
 */
int xTaskSuspend(taskHandle_t taskHandle)
{
    task_t *pTask = (task_t *)taskHandle;
    if(NULL == taskHandle)
    {
        return KERNEL_ERR_HANLE_NULL;
    }
    if(KERNEL_TASK_VALID != pTask->taskValid)
    {
        return KERNEL_ERR_HANLE;
    }

    pTask->taskStatus = KERNEL_TASK_STATUS_SUSPEND;
	taskControl.powerBits &= (~(1<<taskHandle->taskId));
    /* 在任务执行中不能更新任务控制器，否则可能导致任务控制器出现错误!!!! */
    if(KERNEL_TASK_NOT_EXEC == taskControl.taskInExec)
    {
        return xTaskControlUpdate();
    }
    return KERNEL_SUCCESS;
}

/***********************************************************
 *
 * @func	: xSuspendCurrentTask
 *
 * @params	: None;
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 将当前任务挂起(只能在任务内使用，在任务外使用无法确定被挂起的任务);
 *
 * @info	: mq@2024/08/10
 *
 */
int xSuspendCurrentTask(void)
{
    task_t *pTask = (task_t *)taskControl.taskHandle;
    if(NULL == pTask)
    {
        return KERNEL_ERR_HANLE_NULL;
    }
    if(KERNEL_TASK_VALID != pTask->taskValid)
    {
        return KERNEL_ERR_HANLE;
    }

    pTask->taskStatus = KERNEL_TASK_STATUS_SUSPEND;
	taskControl.powerBits &= (~(1<<pTask->taskId));

    /* 在任务执行中不能更新任务控制器，否则可能导致任务控制器出现错误!!!! */
    if(KERNEL_TASK_NOT_EXEC == taskControl.taskInExec)
    {
        return xTaskControlUpdate();
    }
    return KERNEL_SUCCESS;
}


/***********************************************************
 *
 * @func	: xDeleteCurrentTask
 *
 * @params	: None
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 任务将自身删除(只能在任务内使用，且无法清除句柄)
 *
 * @info	: mq@2024/08/10
 *
 */
int xDeleteCurrentTask(void)
{
    task_t *pTask = (task_t *)taskControl.taskHandle;
    if(NULL == pTask)
    {
        return KERNEL_ERR_HANLE_ADDR_NULL;
    }
    if(NULL == pTask)
    {
        return KERNEL_ERR_HANLE_NULL;
    }
    if(KERNEL_TASK_VALID != pTask->taskValid)
    {
        return KERNEL_ERR_HANLE;
    }

    pTask->taskValid = KERNEL_TASK_NOVALID;
    taskControl.taskNum --;
	taskControl.powerBits &= (~(1<<pTask->taskId));

    return KERNEL_SUCCESS;
}

/***********************************************************
 *
 * @func	: xDeleteTask
 *
 * @params	: pTaskHandle : 任务句柄指针; 
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 删除任务
 *
 * @info	: mq@2024/08/10
 *
 */
int xDeleteTask(taskHandle_t *pTaskHandle)
{
	int ret = KERNEL_SUCCESS;
    task_t *pTask = NULL;
    
	/* 任务句柄地址不能为NULL */
    if(NULL == pTaskHandle)
    {
        return KERNEL_ERR_HANLE_ADDR_NULL;
    }
    pTask = (task_t *)(*pTaskHandle);
	/* 任务句柄不能为NULL */
    if(NULL == pTask)
    {
        return KERNEL_ERR_HANLE_NULL;
    }
	/* 判断任务句柄是否有效 */
    if(KERNEL_TASK_VALID != pTask->taskValid)
    {
        return KERNEL_ERR_HANLE;
    }

    pTask->taskValid = KERNEL_TASK_NOVALID;
    taskControl.taskNum --;
	taskControl.powerBits &= (~(1<<pTask->taskId));
	
    /* 在任务执行中不能更新任务控制器，否则可能导致任务控制器出现错误!!!! */
	if(KERNEL_TASK_NOT_EXEC == taskControl.taskInExec)
	{
		ret = xTaskControlUpdate();
	}
	*pTaskHandle = NULL;

    return ret;
}


/***********************************************************
 *
 * @func	: xSetTaskInt
 *
 * @params	: TaskInt : 任务间隔; 
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 设置任务间隔(只能在任务内使用，用于修改自身的间隔)
 *
 * @info	: mq@2024/08/10
 *
 */
int xSetTaskInt(int TaskInt)
{
    if (NULL != taskControl.taskHandle)
    {
        return KERNEL_ERR_CTOL_HANLE_NULL;
    }
    if (KERNEL_TASK_VALID != taskControl.taskHandle->taskValid)
    {
        return KERNEL_ERR_CTOL_HANLE_NOVALID;
    }
    
    taskControl.taskHandle->taskInt = TaskInt;
    return KERNEL_SUCCESS;
}

/***********************************************************
 *
 * @func	: xSetTaskMode
 *
 * @params	: taskMode : 任务模式; 
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 设置任务模式(只能在任务内使用，用于修改自身的任务模式)
 *
 * @info	: mq@2024/08/10
 *
 */
int xSetTaskMode(int taskMode)
{
    if (NULL != taskControl.taskHandle)
    {
        return KERNEL_ERR_CTOL_HANLE_NULL;
    }
    if (KERNEL_TASK_VALID != taskControl.taskHandle->taskValid)
    {
        return KERNEL_ERR_CTOL_HANLE_NOVALID;
    }
    
    taskControl.taskHandle->taskMode = taskMode;
    return KERNEL_SUCCESS;
}


/***********************************************************
 *
 * @func	: xSetTaskPower
 *
* @params	: taskPower : 任务功耗控制模式; 
 *
 * @return	: KERNEL_SUCCESS : 执行成功;    other : 执行失败;
 *
 * @brief	: 设置任务功耗控制模式设置任务模式(只能在任务内使用，用于修改自身的功耗控制模式)
 *
 * @info	: mq@2024/08/10
 *
 */
int xSetTaskPower(int taskPower)
{
    if (NULL != taskControl.taskHandle)
    {
        return KERNEL_ERR_CTOL_HANLE_NULL;
    }
    if (KERNEL_TASK_VALID != taskControl.taskHandle->taskValid)
    {
        return KERNEL_ERR_CTOL_HANLE_NOVALID;
    }
    
    taskControl.taskHandle->taskPower = taskPower;
	taskControl.powerBits &= (~(1<<taskControl.taskHandle->taskId));
    
    if((KERNEL_TASK_STATUS_ACTIVE == taskControl.taskHandle->taskStatus) && (KERNEL_TASK_POWER_ACTIVE == taskPower))
	{
		taskControl.powerBits |= (1<<taskControl.taskHandle->taskId);
	}
	
    return KERNEL_SUCCESS;
}

/***********************************************************
 *
 * @func	: kernelDispatch
 *
* @params	: None
 *
 * @return	: None
 *
 * @brief	: 内核调度
 *
 * @info	: mq@2024/08/10
 *
 */
void kernelDispatch(void)
{
    uint32_t sleep_ms = 0;
    kernelTime_t kernelCurrentTime = getKernelTimestamp();
    if (0 >= taskControl.taskNum)
    {
        return;
    }
    if (NULL == taskControl.taskHandle)
    {
        return;
    }
    if(KERNEL_TASK_VALID != taskControl.taskHandle->taskValid)
    {
        return;
    }

    if(kernelCurrentTime >= taskControl.taskHandle->taskExecuteTime)
    { 
		taskControl.taskInExec = KERNEL_TASK_IN_EXEC;
        taskControl.taskHandle->taskCB();
		taskControl.taskInExec = KERNEL_TASK_NOT_EXEC;
		/* 任务执行过程中能够删除自身，后续的操作不会有影响 */
        if(KERNEL_TASK_MODE_ONCE == taskControl.taskHandle->taskMode)
        {
            taskControl.taskHandle->taskStatus = KERNEL_TASK_STATUS_SUSPEND;
            taskControl.powerBits &= (~(1<<taskControl.taskHandle->taskId));
        }
        else
        {
            taskControl.taskHandle->taskExecuteTime = kernelCurrentTime + taskControl.taskHandle->taskInt*1000;
        }
        xTaskControlUpdate();
    }
    
    /* 低功耗控制 */
    if(0 == taskControl.powerBits)
    {
		if(taskControl.taskNum <= 0)
		{
			/* 异常 - 任务被全部删除 */
            GR_LOG(" [kernel] err... \r\n");
		}
		else
		{
            if(taskControl.taskHandle->taskExecuteTime <= kernelCurrentTime)
            {
                /* 当前的时间大于可执行任务的时间，需要立即执行任务 */
                return;
            }
            sleep_ms = (taskControl.taskHandle->taskExecuteTime-kernelCurrentTime)/1000;
            //只有当需要睡眠时间大于8ms时才允许进入休眠，如果休眠时间很短也进入sleep模式并不会节能，并且会造成任务执行时间出现误差
			if(sleep_ms > 8)
			{
                if(false == EventMaskEmpty())
                {
                    return;
                }
                //实际休眠时间-4ms是应为RTC获取时间戳比较耗时，如果休眠到执行时间会导致任务误差变大
                sleep_ms -= 4;
				/* 进入睡眠模式 */
//                app_timer_start(sleep_timer, sleep_ms, NULL);
                
                
                app_timer_start_api((app_timer_id_t *)&sleep_timer, sleep_ms, NULL); 
                pwr_mgmt_mode_set(PMR_MGMT_SLEEP_MODE);
                pwr_mgmt_schedule();
			}
		}
    }
}

void deleteTask(void)
{
    GR_LOG(" [kernel] task %s \r\n", taskControl.taskHandle->pTaskName);
	xDeleteCurrentTask();
}



/***********************************************************
 *
 * @func	: KERNEL_ERROR_CHECK
 *
 * @params	: status : 状态; 
 *
 * @return	: None
 *
 * @brief	: 打印内核错误状态
 *
 * @info	: mq@2024/08/10
 *
 */
void KERNEL_ERROR_CHECK(int status)
{
    if(KERNEL_SUCCESS == status)
    {
        GR_LOG(" [kernel] check success \r\n");
    }
    else
    {
        GR_LOG(" [kernel] check err, code [%d] \r\n", status);
    }
}

void kernelLoop(void)
{
    int retStatus = 0;
    taskHandle_t task0_Handle = NULL;
    taskHandle_t task1_Handle = NULL;
    taskHandle_t task2_Handle = NULL;
	taskHandle_t task3_Handle = NULL;
	
    kernelInit();
    
//    kernel_rtc_test();

//    retStatus = xCreateTask((taskHandle_t *)&task1_Handle, IdleTask, 500, KERNEL_TASK_MODE_CYCLE, KERNEL_TASK_POWER_ACTIVE, "TASK1-500ms");
//    KERNEL_ERROR_CHECK(retStatus);

    retStatus = xCreateTask((taskHandle_t *)&task2_Handle, IdleTask, 1000, KERNEL_TASK_MODE_CYCLE, KERNEL_TASK_POWER_SLEEP, "TASK2-1000ms");
    KERNEL_ERROR_CHECK(retStatus);

    retStatus = xCreateStaticTask((taskHandle_t *)&task0_Handle, IdleTask, 7, 3600, KERNEL_TASK_MODE_CYCLE, KERNEL_TASK_POWER_SLEEP, "idle task-1000ms");
    KERNEL_ERROR_CHECK(retStatus);
	
	retStatus = xCreateStaticTask((taskHandle_t *)&task3_Handle, deleteTask, 5, 1900, KERNEL_TASK_MODE_CYCLE, KERNEL_TASK_POWER_SLEEP, "delete task-2000ms");
    KERNEL_ERROR_CHECK(retStatus);

    for(;;)
    {
        kernelDispatch();
    }
}


void kernel_loop(void)
{
    uint64_t cureTime = 0;
    uint64_t startTime = getKernelTimestamp()+1000000;
    GR_LOG(" kernel start \r\n");
    delay_ms(5000);
//    kernel_rtc_test();
    kernelLoop();
    for(;;)
    {
        cureTime = getKernelTimestamp();
        if(cureTime > startTime)
        {
            startTime = cureTime+1000000;
            GR_LOG(" kernel time \r\n");
        }
    }
}


